package com.hex.ds.hdrs.common.aspect;

import com.alibaba.fastjson.JSONObject;
import com.hex.bigdata.hbda.utils.RequestHolder;
import com.hex.ds.hdrs.common.base.BaseReq;
import com.hex.ds.hdrs.common.utils.HdrsDateUtil;
import com.hex.ds.hdrs.common.utils.HttpUtils;
import com.hex.ds.hdrs.log.po.ServerInteractLog;
import com.hex.ds.hdrs.log.service.ServerInteractLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @author jdc
 * @date 2020-12-30
 */
@Component
@Aspect
@Slf4j
public class ServerLogAspect {

	//配置文件中中心ip
    @Value("${center.centerIp}")
    private String centerIp;

    private final ServerInteractLogService serverInteractLogService;

    public ServerLogAspect(ServerInteractLogService serverInteractLogService) {
        this.serverInteractLogService = serverInteractLogService;
    }

    @Value("${logging.saveServerLog}")
    private boolean saveServerLog;

    /**
     * 配置切入点
     */
    @Pointcut("@annotation(com.hex.ds.hdrs.common.annotation.ServerLog)")
    public void logPointcut() {
        // 该方法无方法体,主要为了让同类中其他方法使用此切入点
    }

    /**
     * 配置环绕通知,使用在方法logPointcut()上注册的切入点
     *
     * @param joinPoint join point for advice
     */
    @Around("logPointcut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result = joinPoint.proceed();
        ServerInteractLog log = this.getServerInteractLog(joinPoint, result);
        if (saveServerLog) {
            serverInteractLogService.addLog(log);
        }
        return result;
    }

    /**
     * 配置异常通知
     *
     * @param joinPoint join point for advice
     * @param e         exception
     */
    /*@AfterThrowing(pointcut = "logPointcut()", throwing = "e")
    public void logAfterThrowing(JoinPoint joinPoint, BizException e) {
        ServerInteractLog log = this.getServerInteractLog(joinPoint);
        log.setFailReason(e.getErrMsg(), e);
        if (saveServerLog) {
            serverInteractLogService.addLog(log);
        }
    }*/


    /**
     * 日志对象设置参数
     *
     * @param joinPoint
     * @param result
     * @return
     */
    public ServerInteractLog getServerInteractLog(ProceedingJoinPoint joinPoint, Object result) {
        BaseReq params = (BaseReq) joinPoint.getArgs()[0];
        ResponseEntity res = (ResponseEntity)result;
        HttpServletRequest request = RequestHolder.getHttpServletRequest();

        ServerInteractLog log = new ServerInteractLog();
        String status = res.getStatusCode().toString();
        if ("200 OK".equals(status)) {
            log.setReqResult("1");
        } else {
            log.setReqResult("2");
            log.setFailReason(res.getBody().toString());
        }

        log.setInteractType(params.getType());
        log.setFromCode(params.getReqCode());
        log.setFromIp(HttpUtils.getRequestIP(request));
        log.setFromTs(HdrsDateUtil.getCurTs());
        log.setFromJson(JSONObject.toJSON(joinPoint.getArgs()[0]).toString());
        log.setReqUrl(request.getRequestURI());
        log.setToIp(centerIp);
        log.setBackTs(HdrsDateUtil.getCurTs());
        log.setBackJson(JSONObject.toJSON(res).toString());
        return log;
    }


    /**
     * 日志对象设置参数
     *
     * @param joinPoint
     * @return
     */
    /*public ServerInteractLog getServerInteractLog(JoinPoint joinPoint) {
        BaseReq params = (BaseReq) joinPoint.getArgs()[0];
        ServerInteractLog log = new ServerInteractLog();
        HttpServletRequest request = RequestHolder.getHttpServletRequest();
        log.setInteractType(params.getType());
        log.setFromCode(StringUtils.getIp(request));
        log.setFromIp(HttpUtils.getRequestIP(request));
        log.setFromTs(DateUtil.getCurTs());
        log.setFromJson(JSONObject.toJSON(joinPoint.getArgs()[0]).toString());
        log.setReqUrl(request.getRequestURI());

        log.setToIp(centerIp);
        log.setBackTs(DateUtil.getCurTs());
        log.setReqResult("2");
        return log;
    }*/
}
